/*
 * Copyright 2010-2018 Eric Kok et al.
 *
 * Transdroid is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Transdroid is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Transdroid.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.transdroid.core.widget;

import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.widget.RemoteViews;

import androidx.annotation.NonNull;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EReceiver;
import org.transdroid.R;
import org.transdroid.core.app.settings.ApplicationSettings;
import org.transdroid.core.app.settings.ApplicationSettings_;
import org.transdroid.core.app.settings.ServerSetting;
import org.transdroid.core.gui.TorrentsActivity_;
import org.transdroid.core.gui.log.Log_;
import org.transdroid.core.service.ControlService;
import org.transdroid.core.service.ControlService_;

/**
 * The provider of a list-style Transdroid widget, which controls the general loading and (touch) event handling. The list rows' remote views are
 * loaded in the accompanying {@link ListWidgetViewsService}.
 *
 * @author Eric Kok
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@EReceiver
public class ListWidgetProvider extends AppWidgetProvider {

    public static final String INTENT_STARTSERVER = "org.transdroid.START_SERVER";
    public static final String EXTRA_TORRENT = "extra_torrent";
    public static final String EXTRA_SERVER = "extra_server";
    public static final String EXTRA_REFRESH = "extra_refresh";

    @Bean
    protected ApplicationSettings applicationSettings;

    /**
     * Loads and sets up the layout for some specific app widget given the user's widget settings. Note that the views for the list view rows are
     * loaded separately in the {@link WidgetViewsFactory}.
     *
     * @param context     The app widget context, with access to resources
     * @param appWidgetId The specific ID of the app widget to load
     * @param config      The user widget configuration, with filter and theme preferences
     * @return A fully initialised set of remote views to update the widget with the AppWidgetManager
     */
    public static RemoteViews buildRemoteViews(Context context, int appWidgetId, ListWidgetConfig config) {

        // Does the server to show and its widget settings actually still exist?
        if (context == null || config == null) {
            return null;
        }
        ApplicationSettings appSettings = ApplicationSettings_.getInstance_(context);
        if (config.getServerId() < 0 || config.getServerId() > appSettings.getMaxOfAllServers()) {
            Log_.getInstance_(context)
                    .e("ListWidgetProvider", "Tried to set up widget " + appWidgetId + " but the bound server ID " + config.getServerId() +
                            " no longer exists.");
            return null;
        }

		// Load the dark or light widget layout xml
		RemoteViews rv = new RemoteViews(context.getPackageName(),
				config.shouldUseDarkTheme() ? R.layout.widget_torrents_dark : R.layout.widget_torrents);

        // Set up the widget's list view loading service which refers to the WidgetViewsFactory
        Intent data = new Intent(context, ListWidgetViewsService_.class);
        data.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        data.setData(Uri.parse(data.toUri(Intent.URI_INTENT_SCHEME)));
        rv.setRemoteAdapter(appWidgetId, R.id.torrents_list, data);
        Intent open = new Intent(context, TorrentsActivity_.class);
        open.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        rv.setPendingIntentTemplate(R.id.torrents_list, PendingIntent.getActivity(context, appWidgetId, open, PendingIntent.FLAG_UPDATE_CURRENT));
        rv.setEmptyView(R.id.torrents_list, R.id.error_text);
        rv.setTextViewText(R.id.error_text, context.getString(R.string.widget_loading));

        // Show the server and status type filter from the widget configuration in the 'action bar'
        // NOTE: The ListWidgetViewsService will eventually decide to show these labels or the server status statistics
        ServerSetting server = appSettings.getServerSetting(config.getServerId());
        rv.setTextViewText(R.id.server_text, server.getName());
        rv.setTextViewText(R.id.filter_text, config.getStatusType().getFilterItem(context).getName());

        // Set up the START_SERVER intent for 'action bar' clicks to start Transdroid normally
        Intent start = new Intent(context, TorrentsActivity_.class);
        // start.setData(Uri.parse("intent://widget/" + appWidgetId + "/start/" + config.getServerId()));
        start.setAction(INTENT_STARTSERVER);
        start.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        start.putExtra(EXTRA_SERVER, config.getServerId());
        rv.setOnClickPendingIntent(R.id.icon_image, PendingIntent.getActivity(context, appWidgetId, start, PendingIntent.FLAG_UPDATE_CURRENT));
        rv.setOnClickPendingIntent(R.id.navigation_view, PendingIntent.getActivity(context, appWidgetId, start, PendingIntent.FLAG_UPDATE_CURRENT));

        // Set up the widgets refresh button pending intent (calling this WidgetProvider itself)
        // Make sure that the intent is unique using a custom data path (rather than just the extras)
        Intent refresh = new Intent(context, ListWidgetProvider_.class);
        refresh.setData(Uri.parse("intent://widget/" + appWidgetId + "/refresh"));
        refresh.putExtra(EXTRA_REFRESH, appWidgetId);
        refresh.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        rv.setOnClickPendingIntent(R.id.refresh_button, PendingIntent.getBroadcast(context, appWidgetId, refresh, PendingIntent.FLAG_UPDATE_CURRENT));

        // Set up the control (pause and resume) buttons (calling the WidgetProvider itself)
        Intent pauseall = new Intent(context, ListWidgetProvider_.class);
        pauseall.setData(Uri.parse("intent://widget/" + appWidgetId + "/pauseall"));
        pauseall.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        pauseall.setAction(ControlService.INTENT_PAUSEALL);
        rv.setOnClickPendingIntent(R.id.pauseall_button,
                PendingIntent.getBroadcast(context, appWidgetId, pauseall, PendingIntent.FLAG_UPDATE_CURRENT));
        Intent resumeall = new Intent(context, ListWidgetProvider_.class);
        resumeall.setData(Uri.parse("intent://widget/" + appWidgetId + "/resumeall"));
        resumeall.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        resumeall.setAction(ControlService.INTENT_RESUMEALL);
        rv.setOnClickPendingIntent(R.id.resumeall_button,
                PendingIntent.getBroadcast(context, appWidgetId, resumeall, PendingIntent.FLAG_UPDATE_CURRENT));

        return rv;

    }

    @Override
    public void onReceive(Context context, @NonNull Intent intent) {
        super.onReceive(context, intent);

        int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);

        // Refresh a specific app widget
        if (intent.hasExtra(EXTRA_REFRESH)) {
            // Manually requested a refresh for the app widget of which the ID was supplied
            RemoteViews views = buildRemoteViews(context, appWidgetId, applicationSettings.getWidgetConfig(appWidgetId));
            if (views != null) {
                AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, views);
                AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.torrents_list);
            }
            return;
        }

        // No refresh: this is a control intent: copy the action and EXTRA_APPWIDGET_ID to start the control service
        if (intent.getAction().startsWith("org.transdroid.control.")) {
            Intent action = new Intent(context, ControlService_.class);
            action.setAction(intent.getAction());
            action.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            context.startService(action);
        }
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        for (int appWidgetId : appWidgetIds) {
            appWidgetManager.updateAppWidget(appWidgetId, buildRemoteViews(context, appWidgetId, applicationSettings.getWidgetConfig(appWidgetId)));
            appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.torrents_list);
        }
    }

    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        for (int appWidgetId : appWidgetIds) {
            applicationSettings.removeWidgetConfig(appWidgetId);
        }
    }

}
